


/**
 * ----------------------------------1.string--------------------------------------
 * 字符串类型
 * */

    let  userName = "queen"
    let  userHobby:string = "football"
    let userWork:string



/**
 * ----------------------------------2.number--------------------------------------
 * number类型
 * */

    let userAge:number = 20
    let userAge1:number

    // userAge1= "hello"
    let num1:number = 10;
    let num2:number = 0b1010;
    console.log(num2.toString(10));
    


/**
 * ----------------------------------3.boolean-------------------------------------
 * bool类型
 * */

    let buffer: boolean;
    buffer = true 



/**
 * ----------------------------------4.字面量---------------------------------------
 * 字面量(自定义变量类型)：变量的值必须和自定义变量类型值一致
 * 也可以使用字面量去指定变量的类型，通过字面量可以确定变量的取值范围
 * */ 

    let userSex: "男" | "女" | "人妖"

    userSex="男"
    userSex="女"



/**
 * ----------------------------------5.any ----------------------------------------
 * 任何类型 没有类型校验  具有安全隐患
 * */ 

    let anyType: any

    anyType = true;
    anyType = "true";
    anyType = 100;
    anyType = {};

    let userScores:number  =  20
    userScores = anyType;



/**
 * ----------------------------------6.unknown ------------------------------------
 * 未知类型 安全的any类型  
*/
    let  unType: unknown 
    unType = 100;
    unType = "100";
    unType = true;
    unType = [1,2,3,4,5];

    console.log(unType);
    
    // userScores = unType;  //Type 'unknown' is not assignable to type 'number'.

    userScores = unType as number;//as 语法表示的类型断言
    // userScores = <number>unType ;//<数据类型>变量名类型断言

    // 类型断言语法总结如下：
    // 第一种：varible as type
    // 第二种：<type>varible

    if (typeof unType == 'number') {
        userScores = unType;
    }





/**
 * ----------------------------------7.联合类型 | ----------------------------------
 * 通过联合类型将多个类型合并为一个类型
*/
    
    let phone = 13122222222;
    let telphone ="13122222222"

   // 以下变量的类型既可以是字符串也可以是数字
    //   number | string 联合类型
   let userPhone: number | string;

    userPhone = 13122222222;
    userPhone ="13122222222";

/**
 * -----------------------------------8.void----------------------------------------
 * 表示没有任何类型,常用于没有返回值的函数
 * */ 

    function fn(): void {
        console.log("hello");
    }

    let fn2 = (): void => {console.log("hi");}

    console.log(fn());
    console.log(fn2());
    
/**
 * -----------------------------------9.never---------------------------------------
 * 表示用户无法达到的类型
 * 例如never类型是哪些总是会抛出异常或者根本就不会有返回值的函数表达式或者箭头函数表达式的返回值类型（死循环）
 * */ 


        function getEorr(): never {
            throw new Error()
        }


        function fn3(): never {
           while (true) {
            
           }
        }


/**
 * -----------------------------------10.object-------------------------------------
 * TS 的对象类型，其实就是描述对象中的 `属性` `方法` 的类型，因为对象是由属性和方法组成的
*/

        // let obj1 = {}  //字面量直接赋空值不严谨相当于没有类型any,不建议使用
        // let obj2: object  //能够约束对象类型但是对象内部的内容不能约束
        // obj1 = true;  
        // // obj2 = true;  
        // let obj3:{name:string,age:number,id:number}  //通过字面量类型限制对象内容到达类型校验功能
        // obj3 = {id:1000,name:"king",age:18}

        // let obj4: {name:string,age?:number,id:number}  //？可选项  
        // obj4 = {name:"jack",id:10001}

        // // 如果对象的部分内容是不固定的，可以使用语法
        // let obj5: {name:string,id:number,[propName: string | symbol]:any}
        // obj5 = {name:"jack",id:10001,sex:"男",hoby:"篮球"}

/**
 * -----------------------------------11.array--------------------------------------
 * 数组类型:
*/

        let arr1 = []  //相当于 never[]
        // arr1 = [1,2,3,4,5];//不能将类型“number”分配给类型“never”。
        // arr1 = ["h","e"]  //不能将类型“string”分配给类型“never”

        let arr2: number[] = [1,2,3,4,5]
        let arr3: string[] = ["he","llo"]

       //声明了一个值即是string类型有可能是number类型的数组
        // let arr4: (string | number)[] = ["abc",100,200,"he"]
        let arr4: Array<string | number> = ["abc",100,200,"he"]



/**
 * -----------------------------------12.tuple(元组|固定长度)------------------------
 * 元组tuple 固定长度的数组
*/

// 元组
        let arr5: [number,string] = [100,"abc"]

        let arr6: [boolean,undefined,null,number] = [true,undefined,null,100]


/**
 * -----------------------------------13.enum---------------------------------------
 * 枚举类型
 * 枚举成员会被赋值为从 0开始递增的数字，同时也会对枚举值到枚举名进行反向映射：
 * 也可以对枚举类型手动赋值，手动赋值的枚举项会接着上一个枚举项递增
 * 手动赋值的枚举项也可以为小数或负数，此时后续未手动赋值的项的递增步长仍为1：
*/
        let  orderType: number;
        orderType = 0;//表示待付款
        orderType = 1;//已付款 待发货
        orderType = 2;//已发货  未收货
        orderType = 3;//已收货 未评价
        orderType = 4;//已评价  交易未完成
        orderType = 5;//已完成

        enum ordersType {
            "待付款",
            "待发货",
            "未收货",
            "交易未完成",
            "已完成"
        }

        let userOrderType: ordersType 
        userOrderType = ordersType.已完成
        console.log("当前订单的状态是：",userOrderType);
        console.log("枚举：",ordersType);
        
        enum scoreType {
            "不及格" = 59.9,
            "一般",
            "良好" = 79.9,
            "优秀"
        }

        let studentScore: scoreType;
        studentScore = scoreType.一般
        console.log(studentScore);
        studentScore = scoreType.优秀
        console.log(studentScore);

        

/**
 * -----------------------------------14.类型别名 ------------------------------------
 * type 当同一类型（复杂）被多次使用时，可以通过类型别名，简化该类型的使用
 * */ 
// let obj1: {id:string,age:number}
// let obj2: {id:string,work:string}
// let obj3: { id: string, info: {} }
// 对象类型复用
// let obj44: { id: string, [propName: string | symbol]: any }
// let obj55: { id: string, age?: number, work?: string, info?: {} }
// obj55 = { id: '12', age: 20 }

// 设置联合类型
type  objType = {id:string,[propName: string | symbol]: any }
let obj1:objType = {id:"1000","age":19,"hoby":"basketball"}
let obj2:objType = {id:"1000","word":"student"}
let obj3:objType = {id:"1000",info:{}}

type sTY = string
let s1:sTY ="hello"
let s2:sTY ="world"


/**
 * ------------------------------------15.交叉类型 &----------------------------------
 * 通过 & 运算符可以将现有的多种类型叠加到一起成为一种类型，它包含了所需的所有类型的特性
 * 注意
 * 原始类型、字面量类型、函数类型等原子类型合并成交叉类型，是没有任何用处的，
 * */


type obj1Type = {id:number,age:number};
type obj2Type = {name:string,hoby:string} & obj1Type 

let userInfo:obj2Type = {name:"king",hoby:"football",id:1000,age:18}


// type type1 = number;
// type type2 = string & type1;

// let telP:type2 = 13122222222;



















